﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.VisualBasic;
using System.Threading;
using System.IO;
using System.Diagnostics;
using System.IO.Ports;
using Microsoft.Win32.SafeHandles;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows.Forms;

[assembly: log4net.Config.XmlConfigurator(Watch = true)]
namespace Communication
{
    public class Can
    {
        public static log4net.ILog log = log4net.LogManager.GetLogger(typeof(Can));


        #region 常量
        /// <summary>
        /// 传送仓，加试剂1样本系统，滑轨A的CanID
        /// </summary>
        public const int DW_R1_SA_ID = 64;
        /// <summary>
        /// 加试剂2,加底物,滑轨B，C，D，E的CanID
        /// </summary>
        public const int R2_SUB_ID = 80;
        /// <summary>
        /// 小车的CanID
        /// </summary>
        public const int TRANSPORT_INCUBATION_ID = 96;
        /// <summary>
        /// 小车的下级CanID
        /// </summary>
        public const int TRANSPORT_INCUBATION_ID_1 = 97;
        /// <summary>
        /// 孵育箱温控CanID
        /// </summary>
        public const int INCUBATION_ID = 98;
        /// <summary>
        /// 样本系统的CanID
        /// </summary>
        public const int SAMPLE_ID = 128;
        /// <summary>
        /// 检测仓的CanID
        /// </summary>
        public const int DETECT_HOUSE_ID = 112;
        /// <summary>
        /// 泵开关
        /// </summary>
        public const int Pump_ID = 0x83;

        //子芯片CanID
        public const Int16 SA_MoveA_ID = 0x41;
        public const Int16 SB_CupIn_ID = 0x43;
        public const Int16 R1A_Kit1_ID = 0x42;
        public const Int16 R1B_ID = 0x44;
        public const Int16 R2A_Kit2_ID = 0x53;
        public const Int16 R2B_ID = 0x54;
        public const Int16 MoveB_MoveC_Substrate_ID = 0x52;
        public const Int16 MoveD_MoveE_ID = 0x51;
        public const Int16 Incubation_ID = 0x61;
        public const Int16 Detect_ID = 0x71;
        public const Int16 DetectLight_ID = 0x73;//检测板ID
        public const Int16 Barcode_ID = 0x83;

        /// <summary>
        /// 所有阀的ID
        /// </summary>
        public const Int16 IO_CanID = 130;

        /// <summary>
        /// 发送命令结束符
        /// </summary>
        public const string strEnd = "\r";
        #endregion

        #region 变量

        private static System.IO.Ports.SerialPort m_serialPort;

        static bool m_connect = false;
        public static VCI_CAN_OBJ[] mGetBuffer = new VCI_CAN_OBJ[100];    // 从串口获得的数据(为何长度为49？？)

        public delegate void DecodeDelegate(int canID, string str);
        public delegate void SendDelegate(Int16 canID, string command);
        /// <summary>
        /// 接受事件
        /// </summary>
        public static event DecodeDelegate Decode_Receive;
        /// <summary>
        /// 发送命令事件
        /// </summary>
        public static event SendDelegate SendCmdEvent;
        /// <summary>
        /// 发送调试命令事件
        /// </summary>
        public static event SendDelegate SendAdjustEvent;
        static string mCheckStr = "";
        static string mCheckStr62 = "";
        static string mCheck131 = "";


        public static int[] AD1result = new int[8];
        public static int[] AD2result = new int[8];

        public static int[] ReagentTemp = new int[4];
        public static int[] CupTemp = new int[4];


        static byte[] tempAd = new byte[2];
        static int adIndex;
        public struct my_CAN_OBJ
        {
            public int ID;
            public int TimeStamp;
            public byte TimeFlag;
            public byte SendType;
            public byte RemoteFlag;
            public byte ExternFlag;
            public byte DataLen;
            public byte[] data;

            public byte[] Reserved;
        }
        public static int m_dataReceiveNum = 0;

        public static my_CAN_OBJ[] m_receiveBuff = new my_CAN_OBJ[50];

        public static String[] m_receiveIdBuff = new String[32];

        #endregion // -------变量----------

        #region 属性

        #endregion //属性

        #region // 构造函数
        public Can()
        {
        }
        #endregion 构造函数

        #region // 连接设备
        public static bool ConnectCan()
        {
            try
            {
                m_serialPort = new System.IO.Ports.SerialPort("COM3", 9600);
                m_serialPort.Open();

                byte[] sendstrtemp = new byte[3];
                sendstrtemp[0] = 0x01;
                sendstrtemp[1] = 0x31;
                sendstrtemp[2] = 0x0d;
                m_serialPort.Write(sendstrtemp, 0, sendstrtemp.Length);
                m_serialPort.Close();
                m_serialPort.Dispose();
                string[] ArryPort;
                bool getPort = true;

                while (getPort)
                {
                    ArryPort = System.IO.Ports.SerialPort.GetPortNames();
                    foreach (string com3str in ArryPort)
                    {
                        if (com3str == "COM3")
                        {
                            getPort = false;
                            break;

                        }
                    }
                }

                Thread.Sleep(2500);
                m_serialPort = new System.IO.Ports.SerialPort("COM3", 9600);
                m_serialPort.Open();


                m_connect = true;
                return m_connect;
            }
            catch (Exception ex)
            {
                string eee = ex.Message;
                m_connect = false;
                return false;
            }
        }
        //private static void m_serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        //{
        //   // WaitPacket(500);
        //}
        #endregion 连接设备

        #region // 关闭设备
        public static void CloseDevice()
        {
            m_serialPort.Close();
        }
        #endregion 关闭设备

        #region // 发送数据
        public static void SendDataToCan(Int16 canID, string command) //当前函数只考虑了小于16位字符串的事件
        {
            if (m_connect)
            {

                while (command.Length > 8)
                {
                    string strtemp = command.Substring(0, 8);  //截取发送字符串的前8位数据
                    command = command.Remove(0, 8);            //移除此节发送的字符串

                    byte[] sendstrtemp = new byte[strtemp.Length + 2]; //重构发送字符串字节数组 
                    byte[] byteArraytemp = System.Text.Encoding.Default.GetBytes(strtemp);

                    sendstrtemp[0] = Convert.ToByte(canID);
                    sendstrtemp[1] = Convert.ToByte(strtemp.Length + 48);
                    Array.Copy(byteArraytemp, 0, sendstrtemp, 2, byteArraytemp.Length);
                    m_serialPort.Write(sendstrtemp, 0, sendstrtemp.Length);

                    System.Threading.Thread.Sleep(1);
                }

                byte[] sendstr = new byte[command.Length + 2];       //重构发送字符串字节数组 
                byte[] byteArray = System.Text.Encoding.Default.GetBytes(command);

                sendstr[0] = Convert.ToByte(canID);             //ID号
                sendstr[1] = Convert.ToByte(command.Length + 48); //数据位数
                Array.Copy(byteArray, 0, sendstr, 2, byteArray.Length);

                m_serialPort.Write(sendstr, 0, sendstr.Length);

                System.Threading.Thread.Sleep(1);

            }

        }


        #endregion 发送数据

        #region // 发送命令
        public static void SendCan(Int16 id_num, string str)
        {
            if (m_connect)
            {
                if (str.Length < 9)
                {
                    byte[] sendstr = new byte[str.Length + 2];
                    byte[] byteArray = System.Text.Encoding.Default.GetBytes(str);

                    sendstr[0] = Convert.ToByte(id_num);
                    sendstr[1] = Convert.ToByte(str.Length + 48);
                    Array.Copy(byteArray, 0, sendstr, 2, byteArray.Length);
                    //    sendstr[str.Length + 2] = Convert.ToByte(0xff);

                    m_serialPort.Write(sendstr, 0, sendstr.Length);
                    //            System.Diagnostics.Debug.WriteLine("=》11"+ convertToHex(sendstr));
                    System.Threading.Thread.Sleep(10);
                }
                else
                {
                    string strtemp = str.Substring(0, 8);
                    str = str.Remove(0, 8);

                    byte[] sendstrtemp = new byte[strtemp.Length + 2];
                    byte[] byteArraytemp = System.Text.Encoding.Default.GetBytes(strtemp);

                    sendstrtemp[0] = Convert.ToByte(id_num);
                    sendstrtemp[1] = Convert.ToByte(strtemp.Length + 48);
                    Array.Copy(byteArraytemp, 0, sendstrtemp, 2, byteArraytemp.Length);
                    //    sendstr[str.Length + 2] = Convert.ToByte(0xff);

                    m_serialPort.Write(sendstrtemp, 0, sendstrtemp.Length);
                    // System.Diagnostics.Debug.WriteLine("=》" + convertToHex(sendstrtemp));
                    //System.Threading.Thread.Sleep(10);
                    byte[] sendstr = new byte[str.Length + 2];
                    byte[] byteArray = System.Text.Encoding.Default.GetBytes(str);

                    sendstr[0] = Convert.ToByte(id_num);
                    sendstr[1] = Convert.ToByte(str.Length + 48);
                    Array.Copy(byteArray, 0, sendstr, 2, byteArray.Length);
                    //    sendstr[str.Length + 2] = Convert.ToByte(0xff);

                    m_serialPort.Write(sendstr, 0, sendstr.Length);
                    //System.Diagnostics.Debug.WriteLine("=》" + convertToHex(sendstr));
                    System.Threading.Thread.Sleep(10);
                }
            }
            Console.Write(DateTime.Now.ToString("HH:mm:ss.fff") + "," + id_num + ",send:" + str);
            //if (SendAdjustEvent != null)//微调命令
            //{
            //    SendAdjustEvent.Invoke(id_num, str);
            //}
            //if (SendCmdEvent != null)//平常命令
            //{
            //    SendCmdEvent.Invoke(id_num, str);
            //}
        }

        #endregion // 发送命令

        #region // 接收数据
        static string str, tmpstr;
        public static void RecieveData()
        {
            if (m_connect)
            {
                try
                {
                    byte[] buffer = new byte[1];

                    while (m_serialPort.BytesToRead < 3)     // 接收数据还不够处理字节
                    {
                        return;
                    }
                    //处理到未有数据在缓冲区内 
                    while (m_serialPort.BytesToRead != 0) //当处理过快，这部分有可能处理到还未接收到的数组
                    {
                        m_serialPort.Read(buffer, 0, 1); //读取ID值 
                        if (Convert.ToInt32(buffer[0]) > 128)
                        {
                            m_receiveBuff[m_dataReceiveNum].ID = Convert.ToInt32(buffer[0]);


                            m_serialPort.Read(buffer, 0, 1); //读取数据个数
                            m_receiveBuff[m_dataReceiveNum].DataLen = buffer[0];

                            //需要确认之后可读数据是否已经返回  //等待数据位数接收到期。。
                            while (m_serialPort.BytesToRead < m_receiveBuff[m_dataReceiveNum].DataLen)
                            {
                                Thread.Sleep(1);
                            }

                            byte[] buffer2 = new byte[m_receiveBuff[m_dataReceiveNum].DataLen];
                            m_serialPort.Read(buffer2, 0, m_receiveBuff[m_dataReceiveNum].DataLen);
                            m_receiveBuff[m_dataReceiveNum].data = buffer2;


                            System.Diagnostics.Debug.WriteLine(m_receiveBuff[m_dataReceiveNum].ID.ToString() + "=" + m_receiveBuff[m_dataReceiveNum].DataLen.ToString() + ":" + System.Text.Encoding.ASCII.GetString(buffer2));

                            String tmpstr;
                            for (int j = 0; j < m_receiveBuff[m_dataReceiveNum].DataLen; j++)
                            {
                                tmpstr = Convert.ToChar(m_receiveBuff[m_dataReceiveNum].data[j]).ToString();
                                m_receiveIdBuff[m_receiveBuff[m_dataReceiveNum].ID - 129] = m_receiveIdBuff[m_receiveBuff[m_dataReceiveNum].ID - 129] + tmpstr;
                                //str = str + tmpstr;
                            }


                            while (m_receiveIdBuff[m_receiveBuff[m_dataReceiveNum].ID - 129].Contains("\r"))
                            {


                                tmpstr = m_receiveIdBuff[m_receiveBuff[m_dataReceiveNum].ID - 129];
                                //if(m_dataReceiveNum == 151 || m_dataReceiveNum == 154)
                                // {
                                //    if()
                                //}
                                switch (m_receiveBuff[m_dataReceiveNum].ID)
                                {

                                    //case 0x93:
                                    //    lock (xStatus)
                                    //    {
                                    //        xStatus = tmpstr;
                                    //    }
                                    //    break;
                                    //case 0x92:
                                    //    lock (yStatus)
                                    //    {
                                    //        yStatus = tmpstr;
                                    //    }
                                    //    break;
                                    //case 0x91:
                                    //    string c = tmpstr;
                                    //    if (c.StartsWith("01"))
                                    //    {
                                    //        lock (car_X_Status)
                                    //        {
                                    //            car_X_Status = c;
                                    //        }
                                    //    }
                                    //    else if (c.StartsWith("02"))
                                    //    {
                                    //        lock (car_X2_Status)
                                    //        {
                                    //            car_X2_Status = c;
                                    //        }
                                    //    }

                                    //    break;
                                    case DeliveryCupControl.RBeltMotorID: //皮带接受状态
                                        {
                                            DeliveryCupControl.BeltMotorStatus = 1;
                                            break;
                                        }
                                    case DeliveryCupControl.RHookMotorID: //钩子状态
                                        {
                                            DeliveryCupControl.HookMotorStatus = 1;
                                            break;
                                        }
                                    case DeliveryCupControl.RCarMotorID: //小车状态
                                        {
                                            DeliveryCupControl.CarMotorStatus = 1;
                                            break;
                                        }
                                    case DeliveryCupControl.RPoleMotorID: //推杆状态
                                        {
                                            DeliveryCupControl.PoleMotorStatus = 1;
                                            break;
                                        }

                                    case ArmMoveControl.RZ1MotorID://Z轴状态
                                        {
                                            if (tmpstr.StartsWith("01"))
                                            {
                                                if (tmpstr.Contains("=L"))
                                                {
                                                    ArmMoveControl.Z1MotorStatus = 2;

                                                }
                                                else if (tmpstr.Contains("=H"))
                                                {
                                                    ArmMoveControl.Z1MotorStatus = 3;

                                                }
                                                else
                                                {
                                                    ArmMoveControl.Z1MotorStatus = 1;
                                                }
                                            }
                                            else if (tmpstr.StartsWith("02"))
                                            {
                                                if (tmpstr.Contains("=L"))
                                                {
                                                    ArmMoveControl.Z2MotorStatus = 2;

                                                }
                                                else if (tmpstr.Contains("=H"))
                                                {
                                                    ArmMoveControl.Z2MotorStatus = 3;

                                                }
                                                else
                                                {
                                                    ArmMoveControl.Z2MotorStatus = 1;
                                                }
                                            }
                                            break;
                                        }
                                    case ArmMoveControl.RXMotorID: //x轴状态
                                        {
                                            if (tmpstr.Contains("=R"))
                                            {
                                                ArmMoveControl.XMotorStatus = 1;

                                            }
                                            else if (tmpstr.Contains("=E"))
                                            {
                                                DialogResult dr;
                                                dr = MessageBox.Show("已经失步了？", "错误", MessageBoxButtons.YesNo);
                                                if (dr == DialogResult.Yes)
                                                {
                                                    break;
                                                }
                                            }
                                            break;
                                        }
                                    case ArmMoveControl.RYMotorID://y轴状态
                                        {
                                            if (tmpstr.Contains("=R"))
                                            {
                                                ArmMoveControl.YMotorStatus = 1;
                                            }
                                            else if (tmpstr.Contains("=E"))
                                            {
                                                DialogResult dr;
                                                dr = MessageBox.Show("已经失步了？", "错误", MessageBoxButtons.YesNo);
                                                if (dr == DialogResult.Yes)
                                                {
                                                    break;
                                                }
                                            }
                                            break;
                                        }
                                    case ArmMoveControl.RPump1ID: //泵状态
                                        {
                                            if (tmpstr.StartsWith("01"))
                                            {
                                                ArmMoveControl.Pump1Status = 1;
                                            }
                                            else if (tmpstr.StartsWith("02"))
                                            {
                                                ArmMoveControl.Pump2Status = 1;
                                            }
                                            else if (tmpstr.StartsWith("DS5=1"))
                                            {
                                                ArmMoveControl.RubbishBucketStatus = 1;
                                            }
                                            else if (tmpstr.StartsWith("DS5=2"))
                                            {
                                                ArmMoveControl.RubbishBucketStatus = 2;
                                            }
                                            else if (tmpstr.StartsWith("DS6=1"))
                                            {
                                                ArmMoveControl.BucketStatus = 1;
                                            }
                                            else if (tmpstr.StartsWith("DS6=2"))
                                            {
                                                ArmMoveControl.BucketStatus = 2;
                                            }
                                            else if (tmpstr.StartsWith("DS3=1"))
                                            {
                                                ArmMoveControl.DoorStatus = 1;
                                            }
                                            else if (tmpstr.StartsWith("DS3=2"))
                                            {
                                                ArmMoveControl.DoorStatus = 2;
                                            }
                                            break;
                                        }
                                    //检测结果返回值

                                    // 第一通道                     
                                    case 0x9a:
                                        {
                                            string AD1Back = tmpstr;
                                            try
                                            {
                                                if (AD1Back.Contains("A") && AD1Back.Length > 5)
                                                {
                                                    tempAd = System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(tmpstr.Substring(3, 2));
                                                    adIndex = Convert.ToInt32(AD1Back.Substring(1, 1));
                                                    AD1result[adIndex - 1] = bytesToInt2(tempAd, 0);
                                                }
                                            }
                                            catch
                                            {
                                            }
                                            AD1Back = "";
                                            break;
                                        }
                                    //第二通道
                                    case 0x97:
                                        {
                                            string AD2Back = tmpstr;
                                            try
                                            {
                                                if (AD2Back.Contains("A") && AD2Back.Length > 5)
                                                {
                                                    lock (AD2result)
                                                    {
                                                        tempAd = System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(tmpstr.Substring(3, 2));
                                                        int adIndex = Convert.ToInt32(AD2Back.Substring(1, 1));

                                                        AD2result[adIndex - 1] = bytesToInt2(tempAd, 0);
                                                    }
                                                }
                                            }
                                            catch
                                            {

                                            }
                                            AD2Back = "";
                                            break;
                                        }
                                    case 0x96:
                                        {
                                            string RagentBack = tmpstr;

                                            //string[] temps = tmpstr.Split('=');
                                            //ReagentTemp[0] = Convert.ToInt32(tmpstr.Split('=')[1]);
                                            if (tmpstr.Contains("1="))
                                            {
                                                string[] temps = tmpstr.Split('=');
                                                ReagentTemp[0] = Convert.ToInt32(temps[1]);
                                            }
                                            else if (tmpstr.Contains("2="))
                                            {
                                                string[] temps = tmpstr.Split('=');
                                                ReagentTemp[1] = Convert.ToInt32(temps[1]);
                                            }
                                            else if (tmpstr.Contains("4="))
                                            {
                                                string[] temps = tmpstr.Split('=');
                                                ReagentTemp[3] = Convert.ToInt32(temps[1]);
                                            }
                                            //tmpstr = "";
                                            //if (strReturn.Contains("CX"))
                                            //{
                                            //    IncubationBox.Temperature.Clear();
                                            //    string[] temps = strReturn.Split(',');

                                            //    for (int i = 1; i < temps.Length; i++)
                                            //    {
                                            //        if (temps[i].Length > 2)
                                            //        {
                                            //            string temp = temps[i].Insert(temps[i].Length - 2, ".");
                                            //            IncubationBox.Temperature.Add(double.Parse(temp));
                                            //        }

                                            //    }
                                            //    ServiceProvider.Monitor.IncubatorTempurature = IncubationBox.TemperatureAVG;
                                            //}
                                            break;
                                        }
                                    case 0x99:
                                        {
                                            string RagentBack = tmpstr;

                                            System.Diagnostics.Debug.WriteLine("testhh：----" + tmpstr);
                                            log.Error("testhh：----" + tmpstr);
                                            try
                                            {
                                                //同时返回很多的时候

                                                if (RagentBack.Contains("\r"))
                                                {
                                                    string tempstr = RagentBack.Substring(0, RagentBack.IndexOf("\r") + 1);
                                                    if (tempstr.Length == 9)
                                                    {
                                                        CupTemp[Convert.ToInt32(tempstr.Substring(2, 1)) - 1] = Convert.ToInt32(tempstr.Substring(4, 4));
                                                    }
                                                    // CupTemp[Convert.ToInt32(tempstr.Substring(tempstr.LastIndexOf("=") - 1, 1)) - 1] = Convert.ToInt32(tempstr.Substring(tempstr.LastIndexOf("=") + 1, tempstr.IndexOf("\r") - tempstr.LastIndexOf("=") - 1));

                                                }
                                                //if (RagentBack.Contains("\r"))
                                                //{
                                                //  CupTemp[Convert.ToInt32(RagentBack.Substring(RagentBack.LastIndexOf("=") - 1, 1))-1] = Convert.ToInt32(RagentBack.Substring(RagentBack.LastIndexOf("=")+1, RagentBack.IndexOf("\r") - RagentBack.LastIndexOf("=") -1));
                                                //}
                                            }
                                            catch
                                            {

                                            }

                                            //if (tmpstr.StartsWith("MB1=")&& Regex.Matches(RagentBack, @"MB").Count==1)
                                            //{
                                            //    string temps = RagentBack.Substring(RagentBack.IndexOf("=")+1, RagentBack.IndexOf("0x0d")- RagentBack.IndexOf("=") - 1);
                                            //    CupTemp[0] = Convert.ToInt32(temps);
                                            //}
                                            //else if (tmpstr.StartsWith("MB2=") && Regex.Matches(RagentBack, @"MB").Count == 1)
                                            //{
                                            //    string temps = RagentBack.Substring(4, 4);
                                            //    CupTemp[1] = Convert.ToInt32(temps);
                                            //}
                                            //else if (tmpstr.StartsWith("MB3=") && Regex.Matches(RagentBack, @"MB").Count == 1)
                                            //{
                                            //    string temps = RagentBack.Substring(4, 4);
                                            //    CupTemp[2] = Convert.ToInt32(temps);
                                            //}
                                            //else if (tmpstr.StartsWith("MB4=") && Regex.Matches(RagentBack, @"MB").Count == 1)
                                            //{
                                            //    string temps = RagentBack.Substring(4, 4);
                                            //    CupTemp[3] = Convert.ToInt32(temps);
                                            //}

                                            break;
                                        }

                                }

                                if (m_receiveBuff[m_dataReceiveNum].ID != 151 && m_receiveBuff[m_dataReceiveNum].ID != 154)
                                {
                                    System.Diagnostics.Debug.WriteLine("返回的数据是：----" + tmpstr);

                                    log.Error("返回的数据是：----" + tmpstr);
                                    if (tmpstr.IndexOf("\r") == tmpstr.Length - 1)
                                        m_receiveIdBuff[m_receiveBuff[m_dataReceiveNum].ID - 129] = "";
                                    else
                                        m_receiveIdBuff[m_receiveBuff[m_dataReceiveNum].ID - 129] = tmpstr.Remove(0, tmpstr.IndexOf("\r") + 1);  //全部删除 

                                    System.Diagnostics.Debug.WriteLine("chuliwande：----" + m_receiveIdBuff[m_receiveBuff[m_dataReceiveNum].ID - 129]);
                                }
                                else
                                {
                                    System.Diagnostics.Debug.WriteLine("返回的数据是：----" + tmpstr);
                                    if (tmpstr.Length == 6)
                                    {
                                        m_receiveIdBuff[m_receiveBuff[m_dataReceiveNum].ID - 129] = "";
                                    }
                                    else if (tmpstr.Length > 6)
                                    {
                                        m_receiveIdBuff[m_receiveBuff[m_dataReceiveNum].ID - 129] = tmpstr.Remove(0, 6);
                                    }


                                }

                            }
                            m_dataReceiveNum++;
                            //   m_receiveIdBuff[m_receiveBuff[m_dataReceiveNum].ID - 129] = "";
                            if (m_dataReceiveNum > 49)
                                m_dataReceiveNum = 0;
                            //}

                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine("Error:" + System.Text.Encoding.ASCII.GetString(buffer));
                        }
                    }
                }

                catch (Exception ex)
                {
                    string eee = ex.Message;
                    return;
                }
            }
        }

        /// <summary>
        /// 处理接收的数据
        /// </summary>
        /// <param name="i">buffer索引</param>
        /// <param name="isPrint">是否输出</param>
        //private static void RecieveDo(int i,bool isPrint)
        //{
        //    if (mGetBuffer[i].RemoteFlag == 0)
        //    {
        //        str = "  数据:";
        //        if (mGetBuffer[i].DataLen > 8)
        //            mGetBuffer[i].DataLen = 8;
        //        for (int j = 0; j < mGetBuffer[i].DataLen; j++)
        //        {
        //            tmpstr = Convert.ToChar(mGetBuffer[i].data[j]).ToString();
        //            mCheckStr = mCheckStr + tmpstr;
        //            str = str + tmpstr;
        //        }
        //        //判断是否半截
        //        if (mCheckStr.Contains(';'))
        //        {
        //            if (mCheckStr.LastIndexOf(';') == mCheckStr.Length - 1)
        //            {
        //                if(isPrint)
        //                    Console.WriteLine(DateTime.Now.ToLongTimeString() + "，recieve:" + mCheckStr);

        //                if (Decode_Receive != null)
        //                {
        //                    Decode_Receive.Invoke(mCheckStr);
        //                }
        //                mCheckStr = "";
        //            }
        //            else
        //            {
        //                Console.WriteLine("-------------包含半截:" + mCheckStr);
        //            }
        //        }
        //        else
        //        {
        //            Console.WriteLine("----------没有结束符，半截返回:" + mCheckStr);
        //        }
        //    }
        //}
        #endregion 接收数据

        #region // 声明将要用到的动态库“ControlCAN.dll”中的几个函数
        // 打开设备
        [DllImport("ControlCAN.dll", CharSet = CharSet.Auto)]
        internal static extern int VCI_OpenDevice(int DeviceType, int DeviceInd, int Reserved);

        // 关闭设备
        [DllImport("ControlCAN.dll", CharSet = CharSet.Auto)]
        internal static extern int VCI_CloseDevice(int DeviceType, int DeviceInd);

        //  初始化Can对象
        [DllImport("ControlCAN.dll", CharSet = CharSet.Auto)]
        internal static extern int VCI_InitCAN(int DeviceType, int DeviceInd, int CANInd, ref VCI_INIT_CONFIG InitConfig);

        // 获取接收信息
        [DllImport("ControlCAN.dll", CharSet = CharSet.Auto)]
        internal static extern int VCI_GetReceiveNum(int DeviceType, int DeviceInd, int CANInd);

        // 读取错误信息
        [DllImport("ControlCAN.dll", CharSet = CharSet.Auto)]
        internal static extern int VCI_ReadErrInfo(int DeviceType, int DeviceInd, int CANInd, ref VCI_ERR_INFO ErrInfo);

        // 接收
        [DllImport("ControlCAN.dll", CharSet = CharSet.Auto)]
        internal static extern int VCI_Receive(int DeviceType, int DeviceInd, int CANInd, [In, Out] VCI_CAN_OBJ[] Receive, int length, int WaitTime);

        // 启动Can
        [DllImport("ControlCAN.dll", CharSet = CharSet.Auto)]
        internal static extern int VCI_StartCAN(int DeviceType, int DeviceInd, int CANInd);

        // 传输命令
        [DllImport("ControlCAN.dll", CharSet = CharSet.Auto)]
        internal static extern int VCI_Transmit(int DeviceType, int DeviceInd, int CANInd, ref VCI_CAN_OBJ Send, int length);

        #endregion // 声明将要用到的动态库“ControlCAN.dll”中的几个函数

        #region // 检查电机状态（忙与闲）
        public static void CheckMotorStatus_num(Int16 can_id, Int16 m_id)
        {
            string buffer = "";
            byte a = 0;
            bool bIsReady = true;

            //mGetBuffer[0].data[0] = a;

            while (bIsReady)
            {
                SendCan(can_id, m_id.ToString() + "RS" + "\r");

                Thread.Sleep(10);       // 延时10毫秒

                // 将从串口获得的数据转换成字符串
                //for (int i = 0; i < mGetBuffer[0].DataLen - 1; i++)
                //{
                //    buffer = buffer + (char)(mGetBuffer[0].data[i]);
                //}

                // 如果字符串的长度大于5
                if (buffer.Length > 5)
                {
                    // 如果字符串中的第一个字符为CanID
                    if (buffer.Substring(0, 1) == can_id.ToString())
                    {
                        // 如果字符串中第一个等号后的第一个字符为R，则将bIsReady设置为false,跳出循环
                        if (buffer.Substring(buffer.IndexOf("=") + 1, 1) == "R")
                        {
                            bIsReady = false;
                        }
                    }
                }
                buffer = "";
            }
        }
        #endregion // 检查电机状态（忙与闲）       

        #region 写入日志方法
        static bool m_isAccessDenied = false;
        #region // LOG(string log)
        /// <summary>
        /// 记录日志,显示分秒毫秒
        /// </summary>
        /// <param name="log">内容</param>
        public static void LOG(string log)
        {
            //if (m_isAccessDenied) return;

            //string userAppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            string _commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
            //string appPath = Application.ExecutablePath;
            //string userFolder = Application.LocalUserAppDataPath;
            //string version = Application.ProductVersion;
            string _logDirectory = @"H:\MDC2700问题";
            if (!Directory.Exists(_logDirectory))
            {
                Directory.CreateDirectory(_logDirectory);
            }

            //log = DateTime.Now.Minute.ToString().PadLeft(2, '0') + ":"
            //     + DateTime.Now.Second.ToString().PadLeft(2, '0') + "."
            //     + DateTime.Now.Millisecond.ToString().PadLeft(3, '0')
            //     + "  [" + ServiceProvider.nameCurrentClass + "] "
            //     + log;

            log = string.Format("{0:D2}:{1:D2}.{2:D3}", DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond)
                 + log;
            try
            {
                FileStream _stream = File.Open(_logDirectory + "\\log.txt", FileMode.Append);
                StreamWriter _writer = new StreamWriter(_stream);
                Console.WriteLine(log);
                _writer.WriteLine(log);
                _writer.Close();
                _stream.Close();
            }
            catch (Exception Ex)
            {
                Debug.Print(Ex.Message);
                m_isAccessDenied = true;
                return;
            }
        }
        #endregion
        #endregion

        #region // 字节转Int
        /// <summary>
        /// 字节转Int
        /// </summary>

        public static int bytesToInt2(byte[] src, int offset)
        {
            int value;
            value = (int)((src[offset] & 0xFF) << 8)
                         | (src[offset + 1] & 0xFF);
            return Convert.ToInt32(value);

        }
        #endregion // 结构：初始配置
    }

    #region // 结构：嵌套类型，VCI（Virtual Channel Identifier虚拟通道标识符)，VPI虚拟路径标识符)
    /// <summary>
    /// CAN接口卡信息的数据类型
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    internal struct VCI_BOARD_INFO          // 电路板信息
    {
        public int hw_Version;
        public int fw_Version;
        public int dr_Version;
        public int in_Version;
        public int irq_num;                 // 中断请求号，Interrupt request
        public byte can_num;                // can总线号
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
        public byte[] str_Serial_Num;       // 串口号
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
        public byte[] str_hw_Type;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public int[] Reserved;
    }
    #endregion // 结构：嵌套类型，VCI（Virtual Channel Identifier虚拟通道标识符)，VPI（Virtual Path Identifier虚拟路径标识符)

    #region // 结构：Can对象，CAN（Controller Area Network）控制器区域网络
    /// <summary>
    /// 定义CAN信息帧的数据类型
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct VCI_CAN_OBJ             // Can总线对象
    {
        public int ID;                      // ID
        public int TimeStamp;               // 时间标志
        public byte TimeFlag;               // 时间标志
        public byte SendType;               // 发送类型
        public byte RemoteFlag;             // 远程标志
        public byte ExternFlag;             // 外部标志
        public byte DataLen;                // 数据长度
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] data;                 // 数据
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public byte[] Reserved;             // 保留的
    }
    #endregion // 结构：Can对象，CAN（Controller Area Network）控制器区域网络

    #region // 结构：Can状态
    [StructLayout(LayoutKind.Sequential)]
    public struct VCI_CAN_STATUS          // Can总线状态
    {
        public byte ErrInterrupt;           // 错误中断
        public byte regMode;
        public byte regStatus;
        public byte regALCapture;
        public byte regECCapture;
        public byte regEWLimit;
        public byte regRECounter;
        public byte regTECounter;
        public int Reserved;
    }
    #endregion // 结构：Can状态

    #region // 结构：错误信息
    /// <summary>
    /// 定义错误信息的数据类型
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct VCI_ERR_INFO            // 错误信息
    {
        public int ErrCode;                 // 错误码

        // UnmanagedType非托管类型
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public byte[] Passive_ErrData;      // 被动的错误数据
        public byte ArLost_ErrData;         // 丢失的错误数据
    }
    #endregion // 结构：错误信息

    #region // 结构：初始化Can的数据类型
    /// <summary>
    /// 定义初始化CAN的数据类型 
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct VCI_INIT_CONFIG         // 初始配置
    {
        public int AccCode;         // 存取密码（或访问密码）
        public int AccMask;         // 存取掩码（或访问掩码）
        public int Reserved;        // 保留的
        public byte Filter;         // 滤波器\滤光器
        public byte Timing0;        // 定时0
        public byte Timing1;        // 定时1
        public byte Mode;           // 模式
    }
    #endregion // 结构：初始配置




}
